package gu.sql2java.json;

import java.util.Set;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
import com.gitee.l0km.beanfilter.core.json.FastjsonFilterableDeserializer;
import com.google.common.collect.FluentIterable;
import gu.sql2java.BaseBean;
import gu.sql2java.Constant;
import gu.sql2java.RowMetaData;
import gu.sql2java.config.RuntimeConfig;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.MoreObjects.firstNonNull;
import static gu.sql2java.Sql2javaSupport.findSuperClass;


/**
 * implementation of BaseBean class for FastJson {@link JavaBeanDeserializer},<br>
 * 
 * @author guyadong
 *
 */
public class FastjsonDeserializer extends FastjsonFilterableDeserializer implements Constant {
	public FastjsonDeserializer(ParserConfig config, Class<? extends BaseBean> beanClass) {
		super(config, checkNotNull(beanClass,"beanClass is null"), true);
	}
	public FastjsonDeserializer(Class<? extends BaseBean> beanClass) {
		this(ParserConfig.getGlobalInstance(), beanClass);
	}
	@Override
	protected <T> T afterDeserialize(JSONObject json, T instance, Set<String> modifiedReset, Set<String> modifiedSet) {
		BaseBean bean = (BaseBean)instance;
		bean.setNew(firstNonNull(json.getBoolean(FIELD_NEW), true));
		Integer modified = json.getInteger(FIELD_MODIFIED);
		Integer initialized = json.getInteger(FIELD_INITIALIZED);
		if(null != initialized){
			bean.setInitialized(initialized);
		}
		if(null != modified){
			bean.setModified(modified);
		}
		if(!modifiedReset.isEmpty()) {
			bean.resetModified(modifiedReset.toArray(new String[modifiedReset.size()]));
		}
		if(!modifiedSet.isEmpty()) {
			bean.modified(modifiedSet.toArray(new String[modifiedSet.size()]));
		}
		if (null != findSuperClass(RuntimeConfig.getLocalConfig().getResetModifiedIfEqual(), clazz)) {
			bean.resetModifiedIfEqual();
		}
		return instance;
	}

	@Override
	protected void processUndeserialized(JSONObject json, Set<String> deserialized, Set<String> additionalSet, DefaultJSONParser parser) {
		/** 忽略new,initialized,modified字段 */
		deserialized = FluentIterable.from(deserialized).append(FIELD_NEW,FIELD_INITIALIZED,FIELD_MODIFIED).toSet();
		super.processUndeserialized(json, deserialized, additionalSet, parser);
	}
	/**
	 * define FASTJSON deserializer for all class derived from BaseBean using {@link ParserConfig#getGlobalInstance()} 
	 */
	public static void install() {
		install(ParserConfig.getGlobalInstance());
	}
	/**
	 * define FASTJSON deserializer for all class derived from BaseBean  
	 * @param config using {@link ParserConfig#getGlobalInstance()} instead of {@code null} 
	 */
	public static void install(ParserConfig config) {
		config = firstNonNull(config,ParserConfig.getGlobalInstance());
		for(RowMetaData metaData:RowMetaData.allMetaDataList()){
			config.putDeserializer(
					metaData.beanType,
					new FastjsonDeserializer(config,metaData.beanType));
		}
	}

}
